package cn.com.pc.content.domain.metadata;

import cn.com.pc.content.util.DateUtils;
import cn.com.pc.content.util.JsonUtils;
import cn.com.pc.content.util.LocalDateUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.SneakyThrows;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

/**
 * 内容数据类型
 */
public enum ContentDataType {
    String("text", "字符型"),
    Integer("integer", "整型"),
    Long("long", "长整型"),
    Double("double", "浮点型"),
    Boolean("boolean", "布尔型"),
    StringList("text", "字符列表型"),
    IntegerList("integer", "整数列表类型"),
    LongList("long", "长整数列表类型"),
    DoubleList("double", "浮点数列表类型"),
    BooleanList("boolean", "布尔列表类型"),
    StringSet("text", "字符集合类型"),
    IntegerSet("integer", "整数集合类型"),
    LongSet("long", "长整数集合类型"),
    DoubleSet("double", "浮点数集合类型"),
    BooleanSet("boolean", "布尔集合类型"),
    Date("date", "日期类型"),
    Object("object", "对象类型");

    private final String name;
    private final String fullname;

    ContentDataType(String name, String fullname) {
        this.name = name;
        this.fullname = fullname;
    }

    //    @JsonCreator
    public static ContentDataType getSourceByName(String name) {
        for (ContentDataType contentType : values()) {
            if (contentType.getName().equals(name)) {
                return contentType;
            }
        }
        return null;
    }

    //    @JsonValue
    public String getName() {
        return name;
    }

    public String getFullname() {
        return this.fullname;
    }

    @SneakyThrows
    public Object parse(Object value) {
        switch (this) {
            case String:
                return java.lang.String.valueOf(value);
            case Integer:
                return java.lang.Integer.parseInt(java.lang.String.valueOf(value));
            case Long:
                return java.lang.Long.parseLong(java.lang.String.valueOf(value));
            case Double:
                return java.lang.Double.parseDouble(java.lang.String.valueOf(value));
            case Boolean:
                return java.lang.Boolean.parseBoolean(java.lang.String.valueOf(value));
            case Date:
                if (value instanceof java.util.Date) {
                    return value;
                }
                if (value instanceof LocalDateTime) {
                    value = LocalDateUtils.format((LocalDateTime) value);
                }
                return DateUtils.parse(java.lang.String.valueOf(value));
            case StringList:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<List<String>>() {
                });
            case IntegerList:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<List<Integer>>() {
                });
            case LongList:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<List<Long>>() {
                });
            case DoubleList:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<List<Double>>() {
                });
            case BooleanList:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<List<Boolean>>() {
                });
            case StringSet:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<Set<String>>() {
                });
            case IntegerSet:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<Set<Integer>>() {
                });
            case LongSet:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<Set<Long>>() {
                });
            case DoubleSet:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<Set<Double>>() {
                });
            case BooleanSet:
                return JsonUtils.jsonToObj(java.lang.String.valueOf(value), new TypeReference<Set<Boolean>>() {
                });
            default:
                return value;
        }
    }

}
